//! \file
/*
**  Copyright (C) - s2e
**
**  This program is under the terms of the BSD License.
*/

/* libs2e */
#include "utils.h"
#include "pythonXFunctions.h"
#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <string>

#include "bindings.h"


namespace s2e {
  namespace plugins {
    namespace options {
      PyObject*                          callbackAfter              = nullptr;
      PyObject*                          callbackBefore             = nullptr;
      PyObject*                          callbackFini               = nullptr;
      PyObject*                          callbackSyscallEntry       = nullptr;
      PyObject*                          callbackSyscallExit        = nullptr;
    };


    static struct PyModuleDef pluginsModuleDef = {
            PyModuleDef_HEAD_INIT,
            "plugins",
            NULL,
            -1,
            s2e::plugins::pluginsCallbacks,
            NULL, /* m_slots    */
            NULL, /* m_traverse */
            NULL, /* m_clear    */
            NULL, /* m_free     */
    };


    PyObject* initplugins(void) {
      PyObject* pluginsModule = PyModule_Create(&s2e::plugins::pluginsModuleDef);

      if (pluginsModule == nullptr) {
        std::cerr << "Failed to initialize the plugins bindings" << std::endl;
        PyErr_Print();
        exit(1);
      }

      /* ======================= */

      /* Create the INSERT_POINT class */
      PyObject *idCallbackClassName = s2e::plugins::python::xPyString_FromString("INSERT_POINT");
      PyObject *idCallbackClassDict = s2e::plugins::python::xPyDict_New();

      /* Add callback ref into the INSERT_POINT class namespace */
      s2e::plugins::python::xPyDict_SetItemString(idCallbackClassDict, "AFTER",            s2e::plugins::python::PyLong_FromUint32(s2e::plugins::options::CB_AFTER));
      s2e::plugins::python::xPyDict_SetItemString(idCallbackClassDict, "BEFORE",           s2e::plugins::python::PyLong_FromUint32(s2e::plugins::options::CB_BEFORE));
      s2e::plugins::python::xPyDict_SetItemString(idCallbackClassDict, "FINI",             s2e::plugins::python::PyLong_FromUint32(s2e::plugins::options::CB_FINI));
      s2e::plugins::python::xPyDict_SetItemString(idCallbackClassDict, "SYSCALL_ENTRY",    s2e::plugins::python::PyLong_FromUint32(s2e::plugins::options::CB_SYSCALL_ENTRY));
      s2e::plugins::python::xPyDict_SetItemString(idCallbackClassDict, "SYSCALL_EXIT",     s2e::plugins::python::PyLong_FromUint32(s2e::plugins::options::CB_SYSCALL_EXIT));

      /* Create the INSERT_POINT class */
      PyObject *idCallbackClass = s2e::plugins::python::xPyClass_New(nullptr, idCallbackClassDict, idCallbackClassName);

      /* Add namespace into the plugins module */
      PyModule_AddObject(pluginsModule, "INSERT_POINT", idCallbackClass);

      return pluginsModule;
    }


  };
};

